接下來我們就可以將拿到的圖片資訊做一下處裡啦!
因為同種效果可能就有好幾種不同的實作方式,所以在接下來的演算法地方如果有不對之處還請各位大大不吝指教
那首先就從很常見的一個效果,圖像反轉開始吧。我們傳入之前獲得的 Uint8ClampArray
,並且將 R、G、B 都使用 255 - 原本的值。
export const invert = pixelData => {
// 每次跳四個索引,也就是一個像素,不處理透明度
for (let i = 0; i < pixelData.length; i += 4) {
pixelData[i] = 255 - pixelData[i] // red
pixelData[i + 1] = 255 - pixelData[i + 1] // green
pixelData[i + 2] = 255 - pixelData[i + 2] // blue
}
return pixelData
}
接下來修改一下之前的程式,在繪畫至 Canvas
前先經過這一段算法。
const pixelData = context.getImageData(0, 0, cw, ch)
filter.invert(pixelData.data)
context.putImageData(pixelData, 0, 0)
所以如果成功的話應該會看到圖片的效果出現。
原始圖片
顏色反轉
接下來也是一個很常見的效果,將圖片轉成灰色。在三個通道值都相等的情況下,像素會呈現灰色( 0、255 分別代表黑色及白色,而灰度則是依據值多少決定,越大的會越接近白色 )
這個算法會算出 R、G、B 三個的平均值,並且替代原本的值,所以最後三個通道的值都會相等
export const grayscale = pixelData => {
for (let i = 0; i < pixelData.length; i += 4) {
const avg = (pixelData[i] + pixelData[i + 1] + pixelData[i + 2]) / 3
pixelData[i] = avg // red
pixelData[i + 1] = avg // green
pixelData[i + 2] = avg // blue
}
return pixelData
}
一樣我們把效果改成使用轉灰階
const pixelData = context.getImageData(0, 0, cw, ch)
filter.grayscale(pixelData.data)
context.putImageData(pixelData, 0, 0)
看下效果
今天介紹了兩個效果,大家應該會明白,其實不同的效果只是對 R、G、B 做不同的演算處理產生。明天見!